#include <iostream>
struct Base {
   virtual void f() {
       std::cout << "base\n";
   }
};
struct Derived : Base {
    void f() override { // 'override' 可选
        std::cout << "derived\n";
    }
};

int main0()
{
    Base b;
    Derived d;

    // 通过引用调用虚函数
    Base& br = b; // br 的类型是 Base&
    Base& dr = d; // dr 的类型也是 Base&
    br.f(); // 打印 "base"
    dr.f(); // 打印 "derived"

    // 通过指针调用虚函数
    Base* bp = &b; // bp 的类型是 Base*
    Base* dp = &d; // dp 的类型也是 Base*
    bp->f(); // 打印 "base"
    dp->f(); // 打印 "derived"

    // 非虚函数调用
    br.Base::f(); // 打印 "base"
    dr.Base::f(); // 打印 "base"
}

class B0 {
    virtual void do_f(); // 私有成员
 public:
    void f() { do_f(); } // 公开接口
};
struct D0 : public B0 {
    void do_f() override; // 覆盖 B::do_f
};
void B0::do_f() {
        std::cout << "do_f B\n";
}
void D0::do_f() {
        std::cout << "do_f D\n";
}

int main3()
{
    D0 d;
    B0* bp = &d;
    bp->f(); // 内部调用 D::do_f();
}

struct A { virtual void f(); };     // A::f 是虚函数
void A::f() {
        std::cout << "A f()\n";
}
struct B : A { void f(); };         // B::f 覆盖 A::f in B
void B::f() {
        std::cout << "B f()\n";
}
struct C : virtual B { void f(); }; // C::f 覆盖 A::f in C
void C::f() {
        std::cout << "C f()\n";
}
struct D : virtual B {}; // D 不引入覆盖函数，B::f 在 D 中为最终
struct E : C, D  {       // E 不引入覆盖函数，C::f 在 E 中为最终
    using A::f; // 非函数声明，仅令 A::f 能为查找所见
};
int main4() {
   E e;
   e.f();    // 虚调用调用 C::f，e 中的最终覆盖函数
   e.E::f(); // 非虚调用调用 A::f，它在 E 中可见
}
// 若一个函数拥有多于一个最终覆盖函数，则程序非良构： 
struct AA {
    virtual void f();
};
void AA::f() {
        std::cout << "AA f()\n";
}
struct VB1 : virtual AA {
    void f(); // 覆盖 A::f
};
void VB1::f() {
        std::cout << "VB1 f()\n";
}
struct VB2 : virtual AA {
    void f(); // 覆盖 A::f
};
void VB2::f() {
        std::cout << "VB2 f()\n";
}
// struct Error : VB1, VB2 {
//     // 错误：A::f 在 Error 中拥有两个最终覆盖函数
// };
struct Okay : VB1, VB2 {
    void f(); // OK：这是 A::f 的最终覆盖函数
};
void Okay::f() {
        std::cout << "Okay f()\n";
}
struct VB1a : virtual AA {}; // 不声明覆盖函数
struct Da : VB1a, VB2 {
    // Da 中，A::f 的最终覆盖函数是 VB2::f
};
int main5() {
   Da da;
   da.f(); 
   Okay ka;
   ka.f();
}

struct BB {
    virtual void f(int);
};
void BB::f(int a ) {
        std::cout << "BB f()" << a<<"\n";
}
struct DD : BB {
    virtual void f(int) override; // OK，D::f(int) 覆盖 B::f(int)
    // void f(long) override; // 错误：f(long) 不覆盖 B::f(int)
};
// // 若函数以说明符 final 声明，而另一函数试图覆盖之，则程序非良构： 
// struct BB {
//     virtual void f() const final;
// };
// struct DD : BB {
//     void f() const; // 错误：D::f 试图覆盖 final B::f
// };
int main() {
   BB da;
   da.f(3);
}